package org.phytodata.actionengine;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import org.pentaho.platform.util.beans.ActionHarness;

@Path("/groovy/api/console")
public class ConsoleResource {

  private static final Log log = LogFactory.getLog(ConsoleResource.class);

  @POST
  @Path("script")
  @Consumes("application/x-www-form-urlencoded")
  @Produces( { "application/xml", "application/json" })
  public ScriptResult execute(@FormParam("script") String script) throws Exception {
    if (script == null) {
      log.error("No Script requested");
    }

    GroovyEngineAction action = new GroovyEngineAction();

    action.setScriptText(script);
    
    String charset = "UTF-8"; //TODO: parameterize this
    ByteArrayOutputStream scriptOutputStream = new ByteArrayOutputStream();
    action.setScriptOutputStream(scriptOutputStream);
    action.setUseProvidedStreamForSys(true);  //force std out and std err to write to the provided stream
    
    //because we are in a request, pass the session on to the script as well
    //We use ActionHarness to do this since it has built in ability to set anonymous inputs
    ActionHarness harness = new ActionHarness(action);
    harness.setValue("session", PentahoSessionHolder.getSession());

    ScriptResult res = new ScriptResult();
    StringWriter exceptionWriter = new StringWriter();

    /* now execute the action, which will cause a value to be written to the echoMessage property */
    try {
      action.execute();
      Object scriptResult = action.getScriptResult();
      if(scriptResult != null) {
        res.setExecutionResult(scriptResult.toString()); //TODO escape the result
      }
      res.setOutputText(scriptOutputStream.toString(charset));
    } catch (Throwable t) {
      StringWriter sw = new StringWriter();
      t.printStackTrace(new PrintWriter(sw));
      res.setStacktraceText(sw.toString());
    }

    return res;
  }

}
